﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Xml.Serialization;
using System.Collections.ObjectModel;

namespace AssignmentsManage.DataClasses
{
    [XmlRootAttribute(ElementName = "Activity", IsNullable = false)]
    public class Activity : DependencyObject, INotifyPropertyChanged
    {
        #region Constructors

        public Activity()
        {
            DueDate = null;
            ActivityStatusType = EnumInfo.ActivityStatusType.NotStarted;

            if (Grade == null) { Grade = new GradeFraction(); }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="title">A short name or title for the activity</param>
        /// <param name="dueDate">Date which the activity takes place or must be completed by</param>
        /// <param name="courseIn">Course code of the course containing information about the task</param>
        public Activity(string title, DateTime dueDate, string courseInCode)
        {
            Title = title;
            DueDate = dueDate;
            CourseInCode = courseInCode;

            ActivityStatusType = EnumInfo.ActivityStatusType.NotStarted;

            if (Grade == null) { Grade = new GradeFraction(); }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="title">A short name or title for the activity</param>
        /// <param name="dueDate">Date which the activity takes place or must be completed by</param>
        /// <param name="courseIn">Course code of the course containing information about the task</param>
        /// <param name="activityStatusType">Stage the activity completion is at</param>
        /// <param name="activityType">Type of activity</param>
        public Activity(string title, DateTime dueDate, string courseInCode, EnumInfo.ActivityStatusType activityStatusType,
            EnumInfo.ActivityType activityType)
            : this(title, dueDate, courseInCode)
        {
            ActivityStatusType = activityStatusType;
            ActivityType = activityType;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="title">A short name or title for the activity</param>
        /// <param name="dueDate">Date which the activity takes place or must be completed by</param>
        /// <param name="courseIn">Course code of the course containing information about the task</param>
        /// <param name="activityStatusType">Stage the activity completion is at</param>
        /// <param name="activityType">Type of activity</param>
        /// <param name="grade">Final grade recieved for the activity when graded</param>
        public Activity(string title, DateTime dueDate, string courseInCode, EnumInfo.ActivityStatusType activityStatusType,
            EnumInfo.ActivityType activityType, GradeFraction grade)
            : this(title, dueDate, courseInCode, activityStatusType, activityType)
        {
            Grade = grade;
        }

        #endregion

        #region Properties

        private string _Title;
        [XmlElementAttribute("Title")]
        public string Title
        {
            get
            {
                return _Title;
            }
            set
            {
                _Title = value;
                OnPropertyChanged("Title");
            }
        }

        private DateTime? _DueDate;
        [XmlElementAttribute("DueDate")]
        public DateTime? DueDate
        {
            get
            {
                return _DueDate;
            }
            set
            {
                _DueDate = value;
                OnPropertyChanged("DueDate");
                OnPropertyChanged("DateCategory");
            }
        }

        [XmlIgnore()]
        public string DateCategory
        {
            get
            {
                if (DueDate == null || DueDate == new DateTime())
                {
                    return "New Item";
                }
                else if (DueDate.Value < DateTime.Now &&
                !(ActivityStatusType == EnumInfo.ActivityStatusType.Finished || ActivityStatusType == EnumInfo.ActivityStatusType.Graded))
                {
                    return "Past Due";
                }
                else if (ActivityStatusType == EnumInfo.ActivityStatusType.Finished || ActivityStatusType == EnumInfo.ActivityStatusType.Graded)
                {
                    return "Finished";
                }
                else if (DueDate.Value.Date == DateTime.Now.Date)
                {
                    return "Today";
                }
                else if (DueDate.Value.Date == DateTime.Now.AddDays(1).Date)
                {
                    return "Tomorrow";
                }
                else if (DueDate.Value.Date < DateTime.Now.AddDays(7 - (int)DateTime.Now.DayOfWeek).Date)
                {
                    return "Later This Week";
                }
                else
                {
                    return "Later";
                }
            }
        }

        private EnumInfo.ActivityType _ActivityType;
        [XmlElementAttribute("ActivityType")]
        public EnumInfo.ActivityType ActivityType
        {
            get
            {
                return _ActivityType;
            }
            set
            {
                _ActivityType = value;
                OnPropertyChanged("ActivityType");
                OnPropertyChanged("ActivityType_Index");
            }
        }

        private EnumInfo.ActivityStatusType _ActivityStatusType;
        [XmlElementAttribute("ActivityStatusType")]
        public EnumInfo.ActivityStatusType ActivityStatusType
        {
            get
            {
                return _ActivityStatusType;
            }
            set
            {
                _ActivityStatusType = value;
                OnPropertyChanged("ActivityStatusType");
                OnPropertyChanged("ActivityStatusType_Index");
            }
        }

        //private Course _CourseIn;
        //[XmlElementAttribute("CourseIn")]
        //public Course CourseIn
        //{
        //    get
        //    {
        //        return _CourseIn;
        //    }
        //    set
        //    {
        //        _CourseIn = value;
        //        OnPropertyChanged("CourseIn");
        //    }
        //}

        private string _CourseInCode;
        [XmlElementAttribute("CourseInCode")]
        public string CourseInCode
        {
            get
            {
                return _CourseInCode;
            }
            set
            {
                _CourseInCode = value;
                OnPropertyChanged("CourseInCode");
            }
        }

        private GradeFraction _Grade;
        [XmlElementAttribute("Grade")]
        public GradeFraction Grade
        {
            get
            {
                return _Grade;
            }
            set
            {
                _Grade = value;
                OnPropertyChanged("Grade");
            }
        }

        private string _Comments;
        [XmlElementAttribute("Comments")]
        public string Comments
        {
            get
            {
                return _Comments;
            }
            set
            {
                _Comments = value;
            }
        }

        private bool _Flagged;
        [XmlElementAttribute("Flagged")]
        public bool Flagged
        {
            get
            {
                return _Flagged;
            }
            set
            {
                _Flagged = value;
                OnPropertyChanged("Flagged");
            }
        }

        private ObservableCollection<LinkedFile> _LinkedFiles;
        /// <summary>
        /// Collection all files linked to this activity
        /// </summary>
        [XmlArray("LinkedFiles"), XmlArrayItem("LinkedFiles", typeof(LinkedFile))]
        public ObservableCollection<LinkedFile> LinkedFiles
        {
            get
            {
                return _LinkedFiles;
            }
            set
            {
                _LinkedFiles = value;
            }
        }

        [XmlIgnore()]
        public string CommentsPreview
        {
            get
            {
                if (_Comments == null)
                { return String.Empty; }
                else if (_Comments.Length <= 100)
                { return Comments; }
                else { return Comments.Substring(0, 100) + "..."; }
            }
        }

        private bool _EditingStatus_Extra;
        [XmlIgnore()]
        public bool EditingStatus_Extra
        {
            get
            {
                return _EditingStatus_Extra;
            }
            set
            {
                _EditingStatus_Extra = value;
                OnPropertyChanged("EditingStatus_Extra");
            }
        }

        private bool _EditingStatus_Multiple;
        [XmlIgnore()]
        public bool EditingStatus_Multiple
        {
            get
            {
                return _EditingStatus_Multiple;
            }
            set
            {
                _EditingStatus_Multiple = value;
                OnPropertyChanged("EditingStatus_Multiple");
            }
        }

        #endregion

        #region Combobox Index Properties

        [XmlIgnore()]
        public int ActivityStatusType_Index
        {
            get
            {
                return (int)ActivityStatusType;
            }
            set
            {
                ActivityStatusType = (EnumInfo.ActivityStatusType)value;
            }
        }

        [XmlIgnore()]
        public int ActivityType_Index
        {
            get
            {
                return (int)ActivityType;
            }
            set
            {
                ActivityType = (EnumInfo.ActivityType)value;
            }
        }

        #endregion

        #region Methods

        

        #endregion

        #region NotifyChanges

        // Create the OnPropertyChanged method to raise the event
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
